package modelo;

public class Funcion extends Operador
{
    private String nombre;
    private int numArgumentos;

    /**
     * Metodo constructor de una funcion
     *
     * @param nombre el nombre de la funcion
     */
    public Funcion(String nombre)
    {
        // indica que es de tipo unario y es funcion
        super("unFUNCION");
        this.nombre = nombre;
        // luego se establece el numero de argumentos
        numArgumentos = 0;
    }

    /**
     * Evalua la funcion y devuelve un valor
     *
     * @param args los parametros o argumentos de la funcion
     * @return el resultado de ejecutar esta funcion
     */
    @Override
    public double evaluar(double[] args)
    {
        if (this.nombre.equalsIgnoreCase("Sin"))
        {
            return Math.sin(Math.toRadians(args[0]));
        }
        else if (this.nombre.equalsIgnoreCase("Cos"))
        {
            return Math.cos(Math.toRadians(args[0]));
        }
        else if (this.nombre.equalsIgnoreCase("Tan"))
        {
            return Math.tan(Math.toRadians(args[0]));
        }
        else if (this.nombre.equalsIgnoreCase("Log"))
        {
            return Math.log10(args[0]);
        }
        else if (this.nombre.equalsIgnoreCase("sqrt"))
        {
            return Math.sqrt(args[0]);
        }
        else if (this.nombre.equalsIgnoreCase("Fact"))
        {
            return factorial(args[0]);
        }
        else
        {
            throw new ErrorSintaxis("no existe la funcion " + this.nombre);
        }
    }

    public void incrementarNumArgumentos()
    {
        numArgumentos++;
    }

    public void setNumArgumentos(int numArgumentos)
    {
        this.numArgumentos = numArgumentos;
    }

    public int getNumArgumentos()
    {
        return numArgumentos;
    }

    @Override
    public String toString()
    {
        return nombre;
    }

    private double factorial(double numero) throws ErrorSintaxis
    {
        if (numero < 0) {
            throw new ErrorSintaxis("infinity");
        }
        if (numero == 0 || numero == 1) {
            return 1;
        } else {
            return numero * factorial(numero - 1);
        }
    }
}